package com.self.match.model;

import com.self.common.enums.OrderDirection;
import com.self.common.param.Order;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Comparator;
import java.util.Iterator;
import java.util.Map;
import java.util.TreeMap;

/**
 * @version v1.0
 * @ClassName: 委托单账本
 * @Description:
 * @Author: Mac
 */
@Data
@Slf4j
public class OrderBooks {

    /**
     * @Title: 买入的限价交易，价格从从高到低
     * 价格越高，越容易买到
     * 同等价格，按时间顺序
     */
    private TreeMap<BigDecimal,MergeOrder> buyLimitPrice;
    /**
     * @Title: 卖出的限价交易，价格从低到高
     * 价格越低，越容易卖出
     */
    private TreeMap<BigDecimal,MergeOrder> sellLimitPrice;

    /**
     * 交易的币种
     */
    private String symbol;

    /**
     * 交易币种的精度
     */
    private int coinScale;

    /**
     * 基币的精度
     */
    private int baseCoinScale;

    /**
     * 日期格式器
     */
    private SimpleDateFormat dateTimeFormat;

    /**
     * 买方的盘口数据
     */
    private TradePlate buyTradePlate;

    /**
     * 卖方的盘口数据
     */
    private TradePlate sellTradePlate;

    public OrderBooks(String symbol) {
        this(symbol,4, 4);
    }

    public OrderBooks(String symbol, int coinScale, int baseCoinScale) {
        this.symbol = symbol;
        this.coinScale = coinScale;
        this.baseCoinScale = baseCoinScale;
        this.initialize();
    }

    /**
     * 初始化
     */
    public void initialize(){
        log.info("init CoinTrader for symbol {}", symbol);
        //载入比较器
        buyLimitPrice = new TreeMap<>(Comparator.reverseOrder()); //价格从大到小
        sellLimitPrice = new TreeMap<>(Comparator.naturalOrder()); // 价格从小到大
        dateTimeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        buyTradePlate = new TradePlate(symbol,OrderDirection.BUY);
        buyTradePlate = new TradePlate(symbol,OrderDirection.SELL);
    }

    /**
     * @Title: 获取当前的交易队列
     * @Description:
     * @Param [orderDirection]
     * @Return java.util.TreeMap<java.math.BigDecimal,com.self.match.model.MergeOrder>
     * @Author Mac
     * @Throws
     */
    public TreeMap<BigDecimal,MergeOrder> getCurrentOrders(OrderDirection orderDirection){
        return orderDirection == OrderDirection.BUY?this.buyLimitPrice:this.sellLimitPrice;
    }

    /**
     * @Title: 获取当前交易队列的迭代器
     * @Description:
     * @Param [orderDirection]
     * @Return java.util.TreeMap<java.math.BigDecimal,com.self.match.model.MergeOrder>
     * @Author Mac
     * @Throws
     */
    public Iterator<Map.Entry<BigDecimal,MergeOrder>> getCurrentOrderIterator(OrderDirection orderDirection){
        return getCurrentOrders(orderDirection).entrySet().iterator();
    }

    /**
     * @Title: 将订单添加到限价队列里面，限价队列的数据是使用价格和时间排序的
     * @Description:
     * @Param [order]
     * @Return void
     * @Author Mac
     * @Throws
     */
    public void addOrder(Order order){
        TreeMap<BigDecimal, MergeOrder> currentOrders = getCurrentOrders(order.getOrderDirection());
        MergeOrder mergeOrder = currentOrders.get(order.getPrice());
        if (mergeOrder == null){
            mergeOrder = new MergeOrder();
            //不存在new一个放进去
            currentOrders.put(order.getPrice(),mergeOrder);
        }
        //按顺序放入
        mergeOrder.add(order);
        //将新进的单子放到盘口
        if (order.getOrderDirection() == OrderDirection.BUY){
            buyTradePlate.add(order);
        }else{
            sellTradePlate.add(order);
        }
    }

    /**
     * @Title: 从交易队列里面移除
     * @Description:
     * @Param [order]
     * @Return void
     * @Author Mac
     * @Throws
     */
    public void cancelOrder(Order order) {
        TreeMap<BigDecimal, MergeOrder> currentOrders = getCurrentOrders(order.getOrderDirection());
        MergeOrder mergeOrder = currentOrders.get(order.getPrice());
        if (mergeOrder == null || mergeOrder.size() <= 0) {
            return;
        }
        Iterator<Order> iterator = mergeOrder.iterator();
        while (iterator.hasNext()){
            Order next = iterator.next();
            if (next.getOrderId().equals(order.getOrderId())){
                iterator.remove();//移除订单
            }
        }
        //如果合并订单是空的，删除改价格
        if (mergeOrder.size() <= 0){
            currentOrders.remove(order.getPrice());
        }

        if(order.getOrderDirection()==OrderDirection.BUY){
            buyTradePlate.remove(order);
        }else{
            sellTradePlate.remove(order);
        }
    }

    /**
     * 获取排在队列里面的第一个数据
     */
    public Map.Entry<BigDecimal, MergeOrder> getBestSuitOrder(OrderDirection orderDirection) {
        return getCurrentOrders(orderDirection).firstEntry();
    }



}
